﻿#include "frmwebclient.h"
#include "ui_frmwebclient.h"
#include "qthelper.h"
#include "qthelperdata.h"
#include "common/utilities/crc.h"
#include "udpclient.h"
#include <iostream>
#include <QDesktopServices>
#include <QJsonDocument>
#include <QDateTime>
#include "common/utilities/datamanager.h"
#include <QHBoxLayout>
#include <QGridLayout>
#include <QResizeEvent>
#include "common/configmanager/configmanager.h"
frmWebClient::frmWebClient(QWidget *parent) : QWidget(parent), ui(new Ui::frmWebClient),
    m_id(0),
    m_isAlarm(0),
    m_isHandCtrl(false)
{
    //使用布局管理替代硬编码尺寸
    m_LeftbigCircle_Pixmap.load(":/source/BigCircle.png");
    m_LeftsmallCircle_Pixmap.load(":/source/SmallCircle.png");

    m_RightbigCircle_Pixmap.load(":/source/BigCircle.png");
    m_RightsmallCircle_Pixmap.load(":/source/SmallCircle.png");

    //大圆半径
    m_bigCircleRadius = this->geometry().width()*0.01;
    m_smallCircleRadius = m_bigCircleRadius*0.2;
    m_MouseLeftFlag = false;
    m_MouseRightFlag = false;
    adjustCirclesPositionAndSize();
    ui->setupUi(this);
    setMouseTracking(true);
    this->initForm();
    this->initConfig();
    init();
    //m_pathAlarmFile = "E:/wlr/Source/WLR0001/20240705193256/";
   // m_imagePath = "E:\\wlr\\Source\\WLR0001\\20240705-215848.png";
    // 加载图片并绘制红圈
    QPixmap pixmap(m_imagePath);
    ui->labImage->setPixmap(pixmap.scaled(ui->labImage->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
    ui->labImage->setAlignment(Qt::AlignCenter);
    ui->labImage->show();
    m_keyManager = new KeyBoardManger(this);
    m_SiYiCameraCtl = new SiYiCameraControl();
    //m_SiYiCameraCtl->SiYiCameraInit();
    connect(m_keyManager, &KeyBoardManger::SenKeyMsg, this,  &frmWebClient::onSendMsg);
    //实例化视频解码线程
    m_readThread = new readThread();
    m_InfraredThread = new readThread();
    //将解码线程的自定义信号updateImage信号与PlayImage绑定,直接调用槽函数，槽函数不执行完，阻塞
    connect(m_readThread,&readThread::updateImage,ui->playimage,&PlayImage::updateImage,Qt::DirectConnection);
    //将解码线程的自定义播放状态改变的信号与窗口线程的on_PlayState槽函数绑定
    connect(m_readThread,&readThread::playState,this,&frmWebClient::on_playState);

    connect(m_InfraredThread, &readThread::updateImage, ui->playvideo,&PlayImage::updateImage,Qt::DirectConnection);
    //将解码线程的自定义播放状态改变的信号与窗口线程的on_PlayState槽函数绑定
    connect(m_InfraredThread, &readThread::playState,this, &frmWebClient::on_playState);

    connect(ui->siyiBtnConnect, &QPushButton::clicked, m_SiYiCameraCtl, &SiYiCameraControl::SiYiCameraInit);
}

frmWebClient::~frmWebClient(){
    if(m_readThread){
      m_readThread->close();
      //阻塞式等待解码线程执行完毕
      m_readThread->wait();
      delete m_readThread;
    }
    if(m_InfraredThread){
      m_InfraredThread->close();
      //阻塞式等待解码线程执行完毕
      m_InfraredThread->wait();
      delete m_InfraredThread;
    }
    delete ui;
}
void frmWebClient::init(){
    std::shared_ptr<CConfigManager> pCfgManger = CConfigManager::GetInstance();
    if(pCfgManger!= nullptr){
      std::string stdPath = "E:\\wlr\\cfg\\json.cfg";
      std::cout << "stdPath: " << stdPath << std::endl;
      Json::Value tmpValue = Json::Value::null;
      if(!pCfgManger->loadConfig(stdPath, tmpValue)){
          return ;
      }
      if (tmpValue.isMember("ImagePath") && tmpValue["ImagePath"].isString()){
          m_imagePath = tmpValue["ImagePath"].asString().c_str();
      }
      if (tmpValue.isMember("File") && tmpValue["File"].isString()){
          m_pathAlarmFile  = tmpValue["File"].asString().c_str(); //+ "WLR0001/20240705193256/";
      }
      if (tmpValue.isMember("cmd") && tmpValue["cmd"].isString()){
          m_cmd = tmpValue["cmd"].asString().c_str();
      }
    }
}
bool frmWebClient::eventFilter(QObject *watched, QEvent *event)
{
    //双击清空
//    if (watched == ui->txtMain->viewport()) {
//        if (event->type() == QEvent::MouseButtonDblClick) {
//            on_btnClear_clicked();
//        }
//    }

    return QWidget::eventFilter(watched, event);
}

void frmWebClient::initForm(){

    QFont font;
    font.setPixelSize(16);
    QPalette palette = ui->labImage->palette();
    palette.setColor(ui->labImage->backgroundRole(), Qt::black);
    ui->labImage->setAutoFillBackground(true);
    ui->labImage->setPalette(palette);

    //设置读取数据库，数据库模块初始化
    CDataManager::GetInstance().initDB();
    isOk = false;
    m_isStart = false;
    //实例化对象并绑定信号槽
    socket = new QWebSocket("WebSocket", QWebSocketProtocol::VersionLatest, this);
    connect(socket, SIGNAL(connected()), this, SLOT(connected()));
    connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
    connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error()));

    //暂时使用前面两个信号,部分系统上后面两个信号Qt没实现,目前测试到5.15.2
    //在win上如果两组信号都关联了则都会触发,另外一组信号就是多个参数表示是否是最后一个数据包
    connect(socket, SIGNAL(textMessageReceived(QString)), this, SLOT(textMessageReceived(QString)));
    connect(socket, SIGNAL(binaryMessageReceived(QByteArray)), this, SLOT(binaryMessageReceived(QByteArray)));

    //定时器发送数据
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(on_btnSend_clicked()));
    // 服务器地址和端口
    QString serverAddress = AppConfig::RobotIP;
    quint16 serverPort = AppConfig::RobotPort;

    m_client = new UdpClient(QHostAddress(serverAddress), serverPort);
    //创建遥控发送启动句柄
    quint16 ctrlPort = AppConfig::CtrlPort;
    m_handClient = new UdpClient(QHostAddress(serverAddress), ctrlPort);
    // 发送数据，并连接信号以获取发送结果
    connect(ui->btnOpenFolder,&QPushButton::clicked, this, &frmWebClient::openFolder);
    m_handler = std::thread(&frmWebClient::startFtpHandlerProc, this);
    if(m_handler.joinable()){
        m_handler.detach();
    }

}

void frmWebClient::initConfig()
{
    ui->txtServerIP->setText(AppConfig::WebServerIP);
    connect(ui->txtServerIP, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));

    ui->txtServerPort->setText(QString::number(AppConfig::WebServerPort));
    connect(ui->txtServerPort, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));

    ui->txtRobotIp->setText(AppConfig::RobotIP);
    connect(ui->txtRobotIp, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));

    ui->txtRobotPort->setText(QString::number(AppConfig::RobotPort));
    connect(ui->txtRobotPort, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));

    ui->ctlPort->setText(QString::number(AppConfig::CtrlPort));
    connect(ui->ctlPort, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));

    this->initTimer();
}

void frmWebClient::saveConfig()
{
    AppConfig::WebServerIP = ui->txtServerIP->text().trimmed();
    AppConfig::WebServerPort = ui->txtServerPort->text().trimmed().toInt();
    AppConfig::RobotIP = ui->txtRobotIp->text().trimmed();
    AppConfig::RobotPort = ui->txtRobotPort->text().trimmed().toInt();
    AppConfig::CtrlPort = ui->ctlPort->text().trimmed().toInt();
    AppConfig::writeConfig();

    this->initTimer();
}

void frmWebClient::initTimer()
{
    if (timer->interval() != AppConfig::IntervalWebClient) {
        timer->setInterval(AppConfig::IntervalWebClient);
    }

    if (AppConfig::AutoSendWebClient) {
        if (!timer->isActive()) {
            timer->start();
        }
    } else {
        if (timer->isActive()) {
            timer->stop();
        }
    }
}

void frmWebClient::append(int type, const QString &data, bool clear)
{
    static int currentCount = 0;
    static int maxCount = 100;
}

void frmWebClient::connected()
{
    isOk = true;
    ui->btnConnect->setText("断开");
    append(2, "服务器连接");
    append(4, QString("本地地址: %1  本地端口: %2").arg(socket->localAddress().toString()).arg(socket->localPort()));
    append(4, QString("远程地址: %1  远程端口: %2").arg(socket->peerAddress().toString()).arg(socket->peerPort()));
}

void frmWebClient::disconnected()
{
    isOk = false;
    ui->btnConnect->setText("连接");
    append(2, "服务器断开");
}

void frmWebClient::error()
{
    append(4, socket->errorString());
}

void frmWebClient::sendData(const QString &data)
{
    QByteArray buffer;
    if (AppConfig::HexSendWebClient) {
        buffer = QtHelperData::hexStrToByteArray(data);
    } else {
        buffer = data.toUtf8();
    }
    if (AppConfig::AsciiWebClient) {
        socket->sendTextMessage(data);
    } else {
        socket->sendBinaryMessage(buffer);
    }

    append(0, data);
}

void frmWebClient::textFrameReceived(const QString &data, bool isLastFrame)
{
    QString buffer = data;
    append(1, buffer);
    PositionData  posData;
    posData = parsePositionData(data);
    m_bufMap[posData.id] = buffer;
    //使用find() 成员函数
    QDateTime dateTime;
    auto it = m_bufMap.find(posData.id);
    if(it!= m_bufMap.end()){
        //解析dateTime，然后转为对应的格式
        if(!m_isAlarm){
            m_isAlarm = true;
            m_id = posData.id;
            //字符串拼接成目录
            QString dateTimeStr = posData.dateTime.toString("yyyyMMddHHmmss");
            QString basePath = "E:/wlr/Source/" +posData.robotSn + "/";
            m_pathAlarmFile = basePath + dateTimeStr+ "/" + posData.position;
        }
        onShowAlarm();
    }else{
        qDebug() <<" Key not found";
    }
     //自动回复数据,可以回复的数据是以;隔开,每行可以带多个;所以这里不需要继续判断
    if (AppConfig::DebugWebClient) {
        int count = AppData::Keys.count();
        for (int i = 0; i < count; i++) {
            if (AppData::Keys.at(i) == buffer) {
                sendData(AppData::Values.at(i));
                break;
            }
        }
    }
}

void frmWebClient::binaryFrameReceived(const QByteArray &data, bool isLastFrame)
{
    QString buffer;
    if (AppConfig::HexReceiveWebClient) {
        buffer = QtHelperData::byteArrayToHexStr(data);
    } else {
        buffer = QString(data);
    }

    textFrameReceived(buffer, isLastFrame);
}

void frmWebClient::textMessageReceived(const QString &data)
{
    textFrameReceived(data, true);
}

void frmWebClient::binaryMessageReceived(const QByteArray &data)
{
    binaryFrameReceived(data, true);
}

void frmWebClient::on_btnConnect_clicked()
{
    static bool isConnected = false;
    if (ui->btnConnect->text() == "连接" && !isConnected) {
        //打开问题
        qDebug() << "frmWebClient::on_btnConnect_clicked 000000 ";
        QString url = QString("%1:%2%3").arg(AppConfig::WebServerIP).arg(AppConfig::WebServerPort).arg("/ws");
        qDebug() << "url: " << url;
        isConnected = true;
        socket->abort();
        socket->open(QUrl(url));
    } else {
        if (isConnected  && ui->btnConnect->text() == "断开"){
            ui->btnConnect->setText("连接");
            isConnected = false;
            socket->abort();
        }
        if(!m_isStart){
          socket->abort();
        }

    }
}

void frmWebClient::on_btnSave_clicked()
{
    QString data ;
    AppData::saveData(data);
    on_btnClear_clicked();
}

void frmWebClient::on_btnClear_clicked()
{
    append(0, "", true);
}

void frmWebClient::startFtpHandlerProc(){
    while(true){
        if(!m_isStart){
            // 使用 system 函数执行程序
            std::cout << "Executing command: " <<m_cmd.toStdString().c_str()<< std::endl;
            int result = system(m_cmd.toStdString().c_str());
            std::cout <<"result: " << result <<std::endl;
            // 检查执行是否成功
            if (result) {
                std::cerr << "Failed to execute the command." << std::endl;
                m_isStart = true;
                break;
            } else {
                std::cout << "Command executed successfully." << std::endl;
                m_isStart = false;
            }
        }
    }
}

bool frmWebClient::IsProcessRunning(const std::string& processName){
    std::string command = "tasklist /FI \"IMAGENAME eq " + processName + "\"";
    FILE* pipe = _popen(command.c_str(), "r");
    if (!pipe) return false;

    char buffer[128];
    std::string result;
    while (!feof(pipe)) {
        if (fgets(buffer, 128, pipe) != NULL)
            result += buffer;
    }
    _pclose(pipe);

    // 检查输出中是否包含进程名
    return result.find(processName) != std::string::npos;
}
void frmWebClient::HandlerIsExistProc(){
    const char* command = "main.exe";
    while(true){
        if(IsProcessRunning(command)){
            std::cout << "ftp is existed  " << std::endl;
            m_isStart = true;
        }else{
            std::cout << "ftp is not existed " << std::endl;
            m_isStart = false;
        }
        std::this_thread::sleep_for(std::chrono::seconds(10));
    }
}
void frmWebClient::onSendMsg(const QString  &msg){
    //判断消息
    if(m_SiYiCameraCtl!=nullptr){
        if(msg == "Key_W"){
            m_SiYiCameraCtl->handleUp();
        }
        if(msg == "Key_A"){

            m_SiYiCameraCtl->handleLeft();
        }
        if(msg == "Key_S"){

            m_SiYiCameraCtl->handleDown();
        }
        if(msg == "Key_D"){
            m_SiYiCameraCtl->handleRight();
        }
        if(msg == "Key_R"){
            // 按下复位按键
            m_SiYiCameraCtl->handleReset();
        }
    }
    //如果控制机器狗的前后左右按键的话
    if(msg == "Front" || msg == "Back" || msg == "Left"||msg == "Right" || msg == "Key_Enter"){
        qDebug() <<" ===== msg:" << msg;
        SendMsg(msg); //发送UDP消息
    }
}
void frmWebClient::openFolder(){
    qDebug() << "m_pathAlarmFile: " << m_pathAlarmFile;
    QDesktopServices::openUrl(QUrl::fromLocalFile(m_pathAlarmFile));
}
void frmWebClient::drawRedCircle(QPixmap *pixmap, const QPoint &center, int radius) {
    QPainter painter(pixmap);
    painter.setBrush(Qt::red);
    painter.setPen(Qt::NoPen); // 不使用边框
    painter.drawEllipse(center, radius, radius); // 绘制红圈
}

QPixmap frmWebClient::loadAndModifyImage(const QString &filePath, const QPoint &circleCenter, int radius) {
    QPixmap pixmap(filePath);
    if (pixmap.isNull()) {
        qDebug() << "Failed to load image";
        return pixmap;
    }

    drawRedCircle(&pixmap, circleCenter, radius);
    return pixmap;
}

PositionData frmWebClient::parsePositionData(const QString &jsonString){
    PositionData data;
    QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonString.toUtf8());
    if (!jsonDoc.isObject()) {
        qWarning() << "Invalid JSON format";
        return data;
    }
    QJsonObject jsonObj = jsonDoc.object();
    data.id = jsonObj["id"].toInt();
    data.robotSn = jsonObj["robotSn"].toString();
    data.position = jsonObj["position"].toString();
    data.width = jsonObj["width"].toInt();
    data.height = jsonObj["height"].toInt();

    // 解析 dateTime，注意这里需要将字符串转换为合适的日期时间格式
    QString dateTimeStr = jsonObj["dateTime"].toString();
    QDateTime dateTime = QDateTime::fromString(dateTimeStr, Qt::ISODate);
    if (!dateTime.isValid()) {
        qWarning() << "Invalid date time format";
    } else {
        data.dateTime = dateTime;
    }
    return data;
}
void frmWebClient::onShowAlarm(){
    ui->btnShowAlarm->setStyleSheet("QPushButton { background-color: darkred; }");
}

void frmWebClient::on_btnShowAlarm_clicked()
{
   //画出对应的点位，并描点
    qDebug() << "on_btnShowAlarm_clicked m_id:" << m_id;
    static int m_flagId = m_id;
    auto it = m_bufMap.find(m_flagId);
    if(it!= m_bufMap.end()){
        //解析dateTime，然后转为对应的格式
        PositionData  posData;
        posData = parsePositionData(it->second);
        int width = posData.width;
        int height = posData.height;
        QPoint circleCenter(width, height); // 红圈中心点坐标
        int circleRadius = 10; // 红圈半径
        QPixmap pixmap = loadAndModifyImage(m_imagePath, circleCenter, circleRadius);
        ui->labImage->setPixmap(pixmap.scaled(ui->labImage->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
    }else{
        qDebug() <<" Key not found";
        m_flagId = m_id;
    }
    m_flagId ++;
    qDebug() << "on_btnShowAlarm_clicked m_flagId " << m_flagId;
}

void frmWebClient::on_btnStartPatrol_clicked()
{
    static bool isStart = false; //是否开启巡检
    QJsonObject jsonObject;
    QString patrol; // 巡检状态
    if(!isStart && ui->btnStartPatrol->text() == "启动巡检"){
        isStart = true;
        ui->btnStartPatrol->setText("停止巡检");
        patrol= "start";
    }else if(isStart && ui->btnStartPatrol->text() == "停止巡检"){
        isStart = false;
        ui->btnStartPatrol->setText("启动巡检");
        patrol= "stop";
    }
    QString crc = CalculatedCRC::GetInstance().calculateCRC32(patrol);
     //创建json文档转为字符串
    // 创建 JSON 文档
    jsonObject["Patrol"] = patrol;
    jsonObject["Crc"] = crc;
    QJsonDocument jsonDoc(jsonObject);
    // 将 JSON 文档转换为字符串
    QString jsonString = jsonDoc.toJson(QJsonDocument::Compact);
    if(m_handClient!=nullptr){
        m_handClient->sendData(jsonString.toUtf8());
    }
    qDebug() << "on_btnStartPatrol_clicked jsonString = " << jsonString;
}

void frmWebClient::on_btnHandlerCtrl_clicked()
{
    static bool isCtrl = false;
    //手持遥控
    QJsonObject jsonObject;
    QString handCtrl; // 巡检状态
    if(!isCtrl && ui->btnHandlerCtrl->text() == "手持遥控"){
        m_isHandCtrl = true;
        isCtrl = true;
        handCtrl= "start";
        ui->btnHandlerCtrl->setText("遥控中");
        ui->btnHandlerCtrl->setStyleSheet("background-color: yellow;");
    }else if(isCtrl && ui->btnHandlerCtrl->text() == "遥控中") {
        //解除遥控
        m_isHandCtrl = false;
        isCtrl = false;
        handCtrl= "stop";
        ui->btnHandlerCtrl->setText("手持遥控");
        ui->btnHandlerCtrl->setStyleSheet("");
    }
    QString crc = CalculatedCRC::GetInstance().calculateCRC32(handCtrl);
        //创建json文档转为字符串
    // 创建 JSON 文档
    jsonObject["HandCtrl"] = handCtrl;
    jsonObject["Crc"] = crc;
    QJsonDocument jsonDoc(jsonObject);
    // 将 JSON 文档转换为字符串
    QString jsonString = jsonDoc.toJson(QJsonDocument::Compact);
    qDebug() << "on_btnStartPatrol_clicked jsonString = " << jsonString;
    if(m_handClient!= nullptr){
        m_handClient->sendData(jsonString.toUtf8());
    }
}
void frmWebClient::adjustCirclesPositionAndSize(){
    //根据窗体的宽高来设置圆的半径
    m_bigCircleRadius = std::min(width(), height())/8;  //圆的大小不超过窗体的四分之一
    m_smallCircleRadius = m_bigCircleRadius / 3; //小院是大圆的三分之一
    //圆心位于窗体右下方
    m_RightBigCir_xy.setX(width() - m_bigCircleRadius);
    m_RightBigCir_xy.setY(height() - m_bigCircleRadius);

    m_LeftBigCir_xy.setX(m_bigCircleRadius);
    m_LeftBigCir_xy.setY(height() - m_bigCircleRadius);

    m_RightSmallCir_xy = m_RightBigCir_xy;
    m_LeftSmallCir_xy = m_LeftBigCir_xy;
}
void frmWebClient::paintEvent(QPaintEvent *event){
    Q_UNUSED(event);
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.setRenderHints(QPainter::SmoothPixmapTransform);
    //绘制摇杆中的大圆
    painter.drawPixmap(m_RightSmallCir_xy.x()-m_bigCircleRadius,m_RightSmallCir_xy.y()-m_bigCircleRadius,\
                                                                                                    m_bigCircleRadius*2,m_bigCircleRadius*2, m_RightbigCircle_Pixmap);
    //绘制摇杆中的小圆
    painter.drawPixmap(m_RightBigCir_xy.x()-m_smallCircleRadius,m_RightBigCir_xy.y()-m_smallCircleRadius,\
                                                                                                    m_smallCircleRadius*2,m_smallCircleRadius*2, m_RightsmallCircle_Pixmap);

    painter.drawPixmap(m_LeftSmallCir_xy.x()-m_bigCircleRadius,m_LeftSmallCir_xy.y()-m_bigCircleRadius,\
                                                                                                              m_bigCircleRadius*2,m_bigCircleRadius*2,m_LeftbigCircle_Pixmap);
    //绘制摇杆中的小圆
    painter.drawPixmap(m_LeftBigCir_xy.x()-m_smallCircleRadius,m_LeftBigCir_xy.y()-m_smallCircleRadius,\
                                                                                                                m_smallCircleRadius*2,m_smallCircleRadius*2,m_LeftsmallCircle_Pixmap);
}
void frmWebClient::mouseMoveEvent(QMouseEvent *e){
    QPoint rocker_xy; //摇杆所在的实时坐标
    QByteArray xy;
    xy.resize(2);
    int x,y ,lx, ly;
    rocker_xy=e->pos();  //
    if(m_MouseRightFlag&&!m_MouseLeftFlag) //MousePressFlag为true，说明鼠标点击在了大圆内，才进行计算
    {
        //小圆圆心出了大圆则在大圆上90-25=65  65*65=4225
        if(pow((rocker_xy.x()- m_RightSmallCir_xy.x()),2)+pow((rocker_xy.y() - m_RightSmallCir_xy.y()),2)>8100)
        {
            x=int( 90*cos(atan2(abs(rocker_xy.y()-m_RightSmallCir_xy.y()),abs(rocker_xy.x()- m_RightSmallCir_xy.x()))) );
            y=int( 90*sin(atan2(abs(rocker_xy.y()-m_RightSmallCir_xy.y()),abs(rocker_xy.x()- m_RightSmallCir_xy.x()))) );

            //第一象限
            if(rocker_xy.x()>m_RightSmallCir_xy.x()&&rocker_xy.y()>m_RightSmallCir_xy.y())
            {
                m_RightBigCir_xy.setX(x + m_RightSmallCir_xy.x());
                m_RightBigCir_xy.setY(y + m_RightSmallCir_xy.y());
                SendMsg("Front");
            }
            //第二象限
            else if(rocker_xy.x()<m_RightSmallCir_xy.x()&&rocker_xy.y()>m_RightSmallCir_xy.y())
            {
                m_RightBigCir_xy.setX(-x + m_RightSmallCir_xy.x());
                m_RightBigCir_xy.setY(y + m_RightSmallCir_xy.y());
                x=-x;
                SendMsg("Back");
            }
            //第三象限
            else if(rocker_xy.x()<m_RightSmallCir_xy.x()&&rocker_xy.y()<m_RightSmallCir_xy.y())
            {
                m_RightBigCir_xy.setX(-x + m_RightSmallCir_xy.x());
                m_RightBigCir_xy.setY(-y + m_RightSmallCir_xy.y());
                x=-x;
                y=-y;
                SendMsg("Left");
            }
            //第四象限
            else if(rocker_xy.x()>m_RightSmallCir_xy.x()&&rocker_xy.y()<m_RightSmallCir_xy.y())
            {
                m_RightBigCir_xy.setX(x+ m_RightSmallCir_xy.x());
                m_RightBigCir_xy.setY(-y+ m_RightSmallCir_xy.y());
                y=-y;
               SendMsg("Right");
            }
        }
        else
        {
            m_RightBigCir_xy = rocker_xy;
            x=rocker_xy.x()- m_RightSmallCir_xy.x();
            y=rocker_xy.y()- m_RightSmallCir_xy.y();
        }
        xy[0]=char( x );
        xy[1]=char( y );
        //hex发送
        //mycartcp->TCPSend(xy);
        qDebug()<<x<<y;
        update();
    }
    if(!m_MouseRightFlag&&m_MouseLeftFlag){
        if(pow((rocker_xy.x() - m_LeftSmallCir_xy.x()),2)+pow((rocker_xy.y()-m_LeftSmallCir_xy.y()),2)>8100) {
            lx=int( 90*cos(atan2(abs(rocker_xy.y()-m_LeftSmallCir_xy.y()),abs(rocker_xy.x()- m_LeftSmallCir_xy.x()))) );
            ly=int( 90*sin(atan2(abs(rocker_xy.y()-m_LeftSmallCir_xy.y()),abs(rocker_xy.x()- m_LeftSmallCir_xy.x()))) );
            //第一象限
            if(rocker_xy.x()> m_LeftSmallCir_xy.x()&&rocker_xy.y()>m_LeftSmallCir_xy.y())
            {
                m_LeftBigCir_xy.setX(lx+m_LeftSmallCir_xy.x());
                m_LeftBigCir_xy.setY(ly+m_LeftSmallCir_xy.y());
                if(m_SiYiCameraCtl!=nullptr){
                    m_SiYiCameraCtl->handleUp();
                }
            }
            //第二象限
            else if(rocker_xy.x()< m_LeftSmallCir_xy.x()&&rocker_xy.y()>m_LeftSmallCir_xy.y())
            {
                m_LeftBigCir_xy.setX(-lx+m_LeftSmallCir_xy.x());
                m_LeftBigCir_xy.setY(ly+m_LeftSmallCir_xy.y());
                lx=-lx;
                //往下
                if(m_SiYiCameraCtl!=nullptr){
                    m_SiYiCameraCtl->handleDown();
                }
            }
            //第三象限
            else if(rocker_xy.x()<m_LeftSmallCir_xy.x()&&rocker_xy.y()<m_LeftSmallCir_xy.y())
            {
                m_LeftBigCir_xy.setX(-lx+m_LeftSmallCir_xy.x());
                m_LeftBigCir_xy.setY(-ly+m_LeftSmallCir_xy.y());
                lx=-lx;
                ly=-ly;

                if(m_SiYiCameraCtl!=nullptr){
                    m_SiYiCameraCtl->handleLeft();
                }
            }
            //第四象限
            else if(rocker_xy.x()>m_LeftSmallCir_xy.x()&&rocker_xy.y()<m_LeftSmallCir_xy.y())
            {
                m_LeftBigCir_xy.setX(lx+m_LeftSmallCir_xy.x());
                m_LeftBigCir_xy.setY(-ly+m_LeftSmallCir_xy.y());
                ly=-ly;
                //往右边
                if(m_SiYiCameraCtl!=nullptr){
                    m_SiYiCameraCtl->handleRight();
                }
            }
        }else{
            m_LeftBigCir_xy = rocker_xy;
            lx=rocker_xy.x()-m_LeftSmallCir_xy.x();
            ly=rocker_xy.y()-m_LeftSmallCir_xy.y();
        }
        xy[0]=char( lx );
        xy[1]=char( ly );
        //hex发送
        qDebug()<<lx<<ly;
        update();
    }

    m_MapRemov_Old=rocker_xy;
}
void frmWebClient::mousePressEvent(QMouseEvent *e){
    QPoint rocker_xy; //摇杆所在的实时坐标
    rocker_xy=e->pos(); //获取摇杆所在的实时坐标
    qDebug() <<"摇杆坐标： " <<rocker_xy;
    //鼠标点击，在大圆内才设置MousePressFlag
    if(pow((rocker_xy.x()- m_RightSmallCir_xy.x()), 2)+pow((rocker_xy.y() - m_RightSmallCir_xy.y()),2)<=8100) //判断摇杆是否在大圆内
    {
        m_MouseRightFlag = true;
    }
    if (pow((rocker_xy.x() - m_LeftSmallCir_xy.x()),2)+pow((rocker_xy.y()- m_LeftSmallCir_xy.y()),2)<=8100){
         m_MouseLeftFlag = true;
    }
    else
    {
        m_MapRemov_Old=rocker_xy;
    }
}
void frmWebClient::mouseReleaseEvent(QMouseEvent *e){
    Q_UNUSED(e);
    m_MouseLeftFlag = false;
    m_MouseRightFlag = false;
    m_RightBigCir_xy.setX(m_RightSmallCir_xy.x());
    m_RightBigCir_xy.setY(m_RightSmallCir_xy.y());

    m_LeftBigCir_xy.setX(m_LeftSmallCir_xy.x());
    m_LeftBigCir_xy.setY(m_LeftSmallCir_xy.y());
    this->update();
}
void frmWebClient::resizeEvent(QResizeEvent *event){
    adjustCirclesPositionAndSize(); //窗体大小变化时整体调整位置和大小
    QWidget::resizeEvent(event);
}

void frmWebClient::SendMsg(const QString& msg){

    QJsonObject jsonObject;
    QString   keyMsg= msg + QString::number(QDateTime::currentMSecsSinceEpoch());
    //添加CRC校验
    QString crc = CalculatedCRC::GetInstance().calculateCRC32(keyMsg);
        //创建json文档转为字符串
    // 创建 JSON 文档
    jsonObject["KeyType"] = msg;
    jsonObject["TimeStamp"] =QString::number(QDateTime::currentMSecsSinceEpoch());
    jsonObject["Crc"] = crc;
    QJsonDocument jsonDoc(jsonObject);
    // 将 JSON 文档转换为字符串
    QString jsonString = jsonDoc.toJson(QJsonDocument::Compact);
    if(m_client){
        qDebug() <<"jsonString: " << jsonString.toUtf8();
        m_client->sendData(jsonString.toUtf8());
    }
}

void frmWebClient::on_but_file_clicked()
{
    //设置文件过滤器
    QString strName = QFileDialog::getOpenFileName(this,//指定父窗口
                                                   "选择播放视频",//dialog标题
                                                   "/",//从根目录开始
                                                   "视频(*.mp4 *.m4v *.avi *.flv);;其它(*)"//过滤器字符串
                                                   );
    //文件路径获取失败
    if(strName.isEmpty())
    {
        qDebug() << "窗口线程中获取文件路径失败";
        return;
    }
    qDebug() << strName;
    //设置文件路径显示在文本框上

}

//定义视频开始播放按钮的槽函数
void frmWebClient::on_but_open_clicked(){
    //判断有没有视频在播放
    if(ui->but_open->text() == "开始播放"){
        //调用视频读取线程，开始视频解码
        m_readThread->open("rtsp://192.168.1.64:8554/video1");
        m_InfraredThread->open("rtsp://192.168.1.64:8554/video2");
    }
    //有视频在播放，再点击开始播放按钮，应该是停止播放的功能
    else{
        m_readThread->close();
        m_InfraredThread->close();
    }
}

//定义暂停播放按钮的槽函数
void frmWebClient::on_btn_pause_clicked()
{
    if(ui->btn_pause->text() == "暂停播放")
    {
        m_readThread->pause(true);
        m_InfraredThread->pause(true);
        ui->btn_pause->setText("继续播放");
    }
    //继续播放
    else
    {
        m_readThread->pause(false);
        m_InfraredThread->pause(false);
        ui->btn_pause->setText("暂停播放");
    }
}

//定义自定义槽函数playState
void frmWebClient::on_playState(readThread::PlayState state)
{
    //当前在播放视频
    if(state == readThread::play)
    {
        this->setWindowTitle(QString("正在播放: %1").arg(m_readThread->url()));
        ui->but_open->setText("停止播放");
    }
    //没有播放,复原
    else
    {
        ui->but_open->setText("开始播放");
        ui->btn_pause->setText("暂停播放");
        this->setWindowTitle(QString("VideoPlay Version 1.00"));
    }
}
